#!/usr/bin/env python
# encoding: utf-8
"""
Example for using glTools in python. This example relies on pyglet for window
initialization.

MIT License

Copyright (c) 2010, Markus Broecker <mbrckr@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
"""

# try to load pyglet
try:
	import pyglet
	from pyglet.gl import *
except ImportError:
	print "Error importing pyglet!"
	raise RuntimeError


# add the glTools module to the current python path 
import sys
sys.path.append('../python')
# load the module
import glTools


def main():
	# create the window
	window = pyglet.window.Window(800, 600)
	
	# setup OpenGL
	glEnable(GL_DEPTH_TEST)
	
	
	# Load a shader. This shader emulates the transformations of the fixed
	# function pipeline, so we have to set all the parameters as uniforms.
	shader = glTools.Shader('transform.vert', 'transform.frag')
	
	# Create a fbo which we'll use to render to. Note the lower resolution. 
	# We'll display the framebuffer at the end and upscale it to screen
	# resolution.
	render_target = glTools.Framebuffer((640, 480))
	
	# create a vertex list for a ground plane
	vertices = [-20, 0, -20, -20, 0, 20, 20, 0, 20, 20, 0, -20]
	ground_plane = pyglet.graphics.vertex_list(4, ('v3i', vertices))
	
	# create a vertex list for something else

	
	# create a vertex list for a screen filling textured quad
	vertices = [-1, 1, -1, -1, 1, -1, 1, 1]
	texcoord = [0, 1, 0, 0, 1, 0, 1, 1]
	tex_quad = pyglet.graphics.vertex_list(4, ('v2i', vertices), ('t2i', texcoord))

	rotation = 0.0

	
	# the drawing routine
	@window.event
	def on_draw():
		
		# render the scene to the fbo and clear it
		render_target.bind() 
		render_target.clear()
		
		# Enable the shader and set the uniform variables
		shader.bind()
		
		# setup the directional and ambient light
		shader.uniform_float('light.direction', 0.0, 4.0, 4.0)
		shader.uniform_float('light.color', 0.7, 0.7, 0.7)
		shader.uniform_float('ambient_light', 0.2, 0.2, 0.2)
		
		# Setup the camera -- this code should go into your camera class. Note
		# that in this shader the camera is always at a position and looks at
		# something else, similar to gluLookAt.
		shader.uniform_float('camera.position', 15.0, 12.0, 0.0)
		shader.uniform_float('camera.at', 0.0, 0.0, 0.0)
		shader.uniform_float('camera.up', 0.0, 1.0, 0.0)
		shader.uniform_float('camera.fov', 60.0)
		shader.uniform_float('camera.ratio', float(window.width)/window.height)
		shader.uniform_float('camera.near', 1.0)
		shader.uniform_float('camera.far', 100.0)
		
		# render a ground plane
		glNormal3f(0, 1, 0)
		glColor3f(0.5, 0.5, 0.5)
		ground_plane.draw(GL_QUADS)

		# render a second, colored plane ...
		glRotatef(rotation, 0, 1, 0)
		glNormal3f(0, 1, 0)
		glBegin(GL_QUADS)
		glColor3f(1, 0, 0)
		glVertex3f(-2, 4, -2)
		glColor3f(1, 1, 0)
		glVertex3f(-2, 4, 2)
		glColor3f(0, 1, 0)
		glVertex3f(2, 4, 2)
		glColor3f(0, 0, 1)
		glVertex3f(2, 4, -2)
		glEnd()

		# disable the shader and return to regular back-buffer rendering
		shader.disable()
		render_target.disable()
		
		# Display a screen-filling quad with the framebuffer
		# Note that only now we are clearing the window
		glClearColor(0.3, 0, 0, 0)
		window.clear()
		
		glMatrixMode(GL_PROJECTION)
		glLoadIdentity()
		glOrtho(-1, 1, -1, 1, 0, 1)
		glMatrixMode(GL_MODELVIEW)
		glLoadIdentity()
		
		# scale up the framebuffer to cover 90% of the window - just to 
		# highlight that we are dealing with a texture.
		glScalef(0.9, 0.9, 0.9)
		
		glEnable(GL_TEXTURE_2D)
		glBindTexture(GL_TEXTURE_2D, render_target.colorbuffer[0])
		
		tex_quad.draw(GL_QUADS)
		
		glDisable(GL_TEXTURE_2D)

		
		
	while not window.has_exit:
		window.dispatch_event("on_draw")
		window.dispatch_events()
		
		dt = pyglet.clock.tick()
		rotation += dt * 20
		
		window.flip()
		
	
if __name__ == '__main__':
	main()

